package com.cskaoyan.javase.oop1._12block._2static._2notice;

/**
 * 一些细节问题（重要）
 *      1. 静态代码块可以近似看成一个，在类加载时期自动调用的静态成员方法，所以不能在里面访问非静态。（没有对象）
 *      包括this关键字，和后面学习的super关键字，都不能使用。
 *      这意味虽然构造代码块可以给静态成员变量赋值，但静态代码块不能给成员变量赋值。
 *      说白了，还是要搞清楚，谁先谁后执行的问题！
 *
 *      2.当需要使用复杂的代码给静态成员变量赋值时，可以使用静态代码块。
 *       但如果仅仅是简单的赋值，直接显式赋值即可。
 *       总得来说，静态代码块用得不多。
 *
 *
 *     3.静态代码块也经常被用来测试类加载的顺序（重要）
 *      一个类的静态代码块如果没有被执行，说明它没有被完全类加载。
 *
 * @since 10:10
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        System.out.println("hello world!");
        /*
            访问类的静态成员,触发类加载
            在类加载过程中,要执行以下结构:
                1.类中静态成员变量的显式赋值
                2.类中的静态代码块
             上述结构是按照代码书写顺序,从上往下执行
         */
        System.out.println(A.numStatic);
    }
}

class A {
    int num;
    static int numStatic = 10;
    static {
        // Non-statics field 'num' cannot be referenced from a statics context
        /*
            静态上下文:
                1.静态方法
                2.静态代码块
         */
        // System.out.println(num);
        // System.out.println(this);
        System.out.println("A的静态代码块执行了!");
    }
    static B b = new B();
}

class B {
    static {
        System.out.println("B的静态代码块执行了!");
    }
    // B类中成员变量的显式赋值,会在new B的对象的过程中执行
    C c = new C();
}

class C {
    static {
        System.out.println("C的静态代码块执行了!");
    }
}